<?php
/**
 * Created by JetBrains PhpStorm.
 * User: dodasso
 * Date: 7/27/13
 * Time: 1:27 AM
 * To change this template use File | Settings | File Templates.
 */

namespace persistance;

require_once(APP_ROOT . '/modules/persistance/DBConnector.php');
require_once(APP_ROOT . '/modules/log/log.php');
require_once(APP_ROOT . '/modules/log/logCommon.php');
require_once(APP_ROOT . '/modules/common/Errors.php');
require_once(APP_ROOT . '/modules/inventory/InventoryObjectDto.php');

use \PDO;
use persistance\DBConnector;
use log\Log;
use log\LogCommon;
use common\Errors;
use inventory\InventoryObjectDto;

class InventoryObjectPersistance {
    /**
     * @var DBConnector
     */
    private $db;

    /**
     * @var boolean
     */
    private $initialized;

    public function __construct() {
        $this->db          = null;
        $this->initialized = false;
    }

    public function __destruct() {
    }

    public function init($db) {
        if((is_null($db)) || !($db instanceof DBConnector)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Invalid parameters.");
            return false;
        }

        $this->db          = $db;
        $this->initialized = true;

        return true;
    }

    private function inventoryObjectFromStatementResult($rsa) {
        Log::LOG_PERSISTANCE_FB();

        if((is_null($rsa)) || (count($rsa) != 1)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Invalid parameters.");
            return null;
        }

        $rs                    = $rsa[0];
        $obj                   = new InventoryObjectDto();
        $obj->id               = intval($rs['id']);
        $obj->name             = $rs['name'];
        $obj->lineOfBusinessId = $rs['line_of_business_id'];
        $obj->measuringUnitId  = $rs['measuring_unit_id'];
        $obj->createdAt        = $rs['created_at'];
        $obj->updatedAt        = $rs['updated_at'];
        $obj->deletedAt        = $rs['deleted_at'];

        Log::LOG_PERSISTANCE_FE();

        return $obj;
    }

    private function inventoryObjectsFromStatementResult($rsa) {
        Log::LOG_PERSISTANCE_FB();

        if((is_null($rsa)) || (empty($rsa))) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Invalid parameters.");
            return null;
        }

        $array = array();
        foreach($rsa as $rs) {
            $obj = $this->inventoryObjectFromStatementResult(array($rs));
            array_push($array, $obj);
        }

        Log::LOG_PERSISTANCE_FE();

        return $array;
    }

    /**
     * @param $id
     * @return array
     */
    public function findById($id) {
        Log::LOG_PERSISTANCE_FB();

        if((is_null($id)) || (!is_int($id))) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Invalid parameters.");
            return array('error'=>ERRORS::INTEGRAL_ERR_INVALID_PARAMETERS);
        }

        if((!$this->initialized)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Not initialized.");
            return array('error'=>ERRORS::INTEGRAL_ERR_PERSISTANCE_NOT_INITIALIZED);
        }
        
        if(!$this->db->isConnected()) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Not connected to DB.");
            return array('error'=>ERRORS::INTEGRAL_ERR_PERSISTANCE_NOT_CONNECTED);
        }

        $query = 'SELECT *' .
                 ' FROM inventory_object' .
                 ' WHERE id = ?';
        $rsa = $this->db->query($query,
            array(array($id, PDO::PARAM_INT, null)));

        if($this->db->lastDBErrorCode() != null) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeCritical, 'Unable to execute query. ' .
                implode(' ', $this->db->lastDBErrorInfo()));
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_UNABLE_TO_READ);
        }
        if((is_null($rsa)) || (empty($rsa))) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeNotice, 'Inventory object not found. Id: ' . $id);
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_NOT_FOUND);
        }

        $obj = $this->inventoryObjectFromStatementResult($rsa);
        if(is_null($obj)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeCritical, 'Unable to map inventory object. Id: ' . $id);
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_UNABLE_TO_MAP_OBJECT);
        }

        Log::LOG_PERSISTANCE_FE();

        return array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$obj);
    }

    public function findByName($name, $like) {
        Log::LOG_PERSISTANCE_FB();

        if((is_null($name)) || (!is_string($name)) ||
           (!is_bool($like))) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Invalid parameters.");
            return array('error'=>ERRORS::INTEGRAL_ERR_INVALID_PARAMETERS);
        }

        if((!$this->initialized)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Not initialized.");
            return array('error'=>ERRORS::INTEGRAL_ERR_PERSISTANCE_NOT_INITIALIZED);
        }

        if(!$this->db->isConnected()) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Not connected to DB.");
            return array('error'=>ERRORS::INTEGRAL_ERR_PERSISTANCE_NOT_CONNECTED);
        }

        $query = 'SELECT *' .
                 ' FROM inventory_object';

        $rsa = null;
        if($like) {
            $query = $query . ' WHERE name LIKE ?';
            $rsa = $this->db->query($query,
                array(array($name . '%', PDO::PARAM_STR, 60)));
        } else {
            $query = $query . ' WHERE name = ?';
            $rsa = $this->db->query($query,
                array(array($name, PDO::PARAM_STR, 60)));
        }

        if($this->db->lastDBErrorCode() != null) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeCritical, 'Unable to execute query. ' .
                implode(' ', $this->db->lastDBErrorInfo()));
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_UNABLE_TO_READ);
        }
        if((is_null($rsa)) || (empty($rsa))) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeNotice, 'Inventory object not found. Name: ' .
                $name);
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_NOT_FOUND);
        }

        $obj = $this->inventoryObjectsFromStatementResult($rsa);
        if(is_null($obj)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeCritical, 'Unable to map inventory object. Name: ' .
                $name);
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_UNABLE_TO_MAP_OBJECT);
        }

        Log::LOG_PERSISTANCE_FE();

        return array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$obj);
    }

    public function listNotDeleted() {
        Log::LOG_PERSISTANCE_FB();

        if((!$this->initialized)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Not initialized.");
            return array('error'=>ERRORS::INTEGRAL_ERR_PERSISTANCE_NOT_INITIALIZED);
        }

        if(!$this->db->isConnected()) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeError, "Not connected to DB.");
            return array('error'=>ERRORS::INTEGRAL_ERR_PERSISTANCE_NOT_CONNECTED);
        }

        $query = 'SELECT *' .
                 ' FROM inventory_object' .
                 ' WHERE deleted_at IS NULL';
        $rsa = $this->db->query($query, null);

        if($this->db->lastDBErrorCode() != null) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeCritical, 'Unable to execute query. ' .
                implode(' ', $this->db->lastDBErrorInfo()));
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_UNABLE_TO_READ);
        }
        if((is_null($rsa)) || (empty($rsa))) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeNotice, 'Zero measuring untis found.');
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_NOT_FOUND);
        }

        $obj = $this->inventoryObjectsFromStatementResult($rsa);
        if(is_null($obj)) {
            Log::LOG_PERSISTANCE(LogCommon::logTypeCritical, 'Unable to map measuring units.');
            return array('error'=>Errors::INTEGRAL_ERR_PERSISTANCE_UNABLE_TO_MAP_OBJECT);
        }

        Log::LOG_PERSISTANCE_FE();

        return array('error'=>Errors::INTEGRAL_ERR_NONE, 'data'=>$obj);
    }
}